/// <summary>
/// Defines a full 3D box to be rendered.
/// </summary>
struct Box
{
public:
	/// <summary>
	/// The position of this box relative to the position of the block.
	/// </summary>
	Point3i		Position;

	/// <summary>
	/// The bounds of this box.
	/// </summary>
	Point3i		Bounds;

	/// <summary>
	/// Initializes a new instance of the <see cref="Box" /> struct.
	/// </summary>
	/// <param name="texture">The texture that this box will use.</param>
	/// <param name="bounds">The bounds of the box.</param>
	/// <param name="pos">The position of the box relative to the position of the block.</param>
	Box(ITexture *texture = null, const Point3i &bounds = Point3i(16, 16, 16), const Point3i &pos = Point3i::Zero);
	
	/// <summary>
	/// Unwraps the box in a similar format that Minecraft handles box-shaped textures.
	/// This can be used to quickly unwrap models, such as chests.
	/// </summary>
	/// <param name="topLeftOfFront">The top-left of the north face.</param>
	/// <returns>The current box instance.</returns>
	Box &Unwrap(const Point2i &topLeftOfFront);

	/// <summary>
	/// Automatically assigns all of the texture coordinates based on
	/// the position given.
	/// </summary>
	/// <param name="coord">The coordinates to base on.</param>
	/// <returns>The current box instance.</returns>
	Box &SetCoordsFromBounds(const Point2i &coord);
	
	/// <summary>
	/// Sets the texture coordinates & color for a specific side of the box.
	/// </summary>
	/// <param name="index">The direction to assign.</param>
	/// <param name="texCoord">The texture coord.</param>
	/// <param name="color">The color.</param>
	/// <returns>The current box instance.</returns>
	Box &SetIndex(const int &index, const Point2i &texCoord, const Colorb &color = Colorb_White);
	
	/// <summary>
	/// Sets a range of sides to the specified texture coordinates & color.
	/// </summary>
	/// <param name="start">The start range.</param>
	/// <param name="end">The end range.</param>
	/// <param name="texCoord">The texture coord.</param>
	/// <param name="color">The color.</param>
	/// <returns>The current box instance.</returns>
	Box &SetRange(const int &start, const int &end, const Point2i &texCoord, const Colorb &color = Colorb_White);

	Box &SetNorth(const Point2i &texCoord, const Colorb &color = Colorb_White);
	Box &SetEast(const Point2i &texCoord, const Colorb &color = Colorb_White);
	Box &SetSouth(const Point2i &texCoord, const Colorb &color = Colorb_White);
	Box &SetWest(const Point2i &texCoord, const Colorb &color = Colorb_White);
	Box &SetBottom(const Point2i &texCoord, const Colorb &color = Colorb_White);
	Box &SetTop(const Point2i &texCoord, const Colorb &color = Colorb_White);
	Box &SetSides(const Point2i &texCoord, const Colorb &color = Colorb_White);
	Box &SetAll(const Point2i &texCoord, const Colorb &color = Colorb_White);

	/// <summary>
	/// Sets the inset of a face. This will inset (or outset, if negative) a face by a specific amount of
	/// units (1 unit = 1/16th of a block). 
	/// </summary>
	/// <param name="index">The direction index.</param>
	/// <param name="value">The value.</param>
	/// <returns>The current box instance.</returns>
	Box &SetInset(const int &index, const int &value);

	Box &SetNorthInset(const int &value);
	Box &SetEastInset(const int &value);
	Box &SetSouthInset(const int &value);
	Box &SetWestInset(const int &value);
	Box &SetBottomInset(const int &value);
	Box &SetTopInset(const int &value);
	
	Box &SetSidesInset(const int &value);
};